package org.september.pisces.filestore.service.hik;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONObject;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Random;

@Service
public class ImageClientImpl {


    @Autowired
    private HikPoolService poolService;

    private final String endStr = "\r\n";
    private final String twoHyphens = "--";
    private final String boundaryStr = "**************";
    private final String divide = twoHyphens + boundaryStr;
    private final String tail_str = divide + twoHyphens + endStr + endStr;
    private final String contentType = "multipart/form-data";
    private final String PREFIX = "hikcstor";
    private final String BEST_NODE = "/HikCStor/BestNode";
    private final String UPLOAD_PIC_URI = "/HikCStor/Picture/Write";


    public String getBestNode(String serialID) {
        return poolService.getBestNode(BEST_NODE + "?SerialID=" + serialID + "&PoolID=" + HikPoolService.imagePoolId + "&Replication=0",
                PREFIX, 0, "text/json");
    }


//    public String uploadImageFile(String path) {
//        try {
//            File file = new File(path);
//            if (!file.exists()) {
//                log.error("file does not exist");
//                return null;
//            }
//            byte[] bytes = ByteArrayUtil.inputStream2ByteArray(path);
//            return uploadImage(bytes);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//    }

    public String uploadImage(byte[] data) throws IOException {
        String gmtTime = GmtTimeUtil.getGmtTime();
        String serialID = new Random().nextInt(1000000) + "";
        String authorization = poolService.postAuth(PREFIX, contentType, gmtTime, UPLOAD_PIC_URI, 0);
        String bestNode = getBestNode(serialID);
        JSONObject node = new JSONObject(bestNode);
        String uri = "http://" + node.getStr("GatewayIP") + ":" + node.getStr("GatewayPort") + UPLOAD_PIC_URI;
        PostMethod postMethod = new PostMethod(uri);
        String body = generateRequestBody(serialID, node.getStr("Token"), data.length);
        postMethod = generateHttpHeader(postMethod, gmtTime, authorization);
        byte[] bodyAndPic = ByteArrayUtil.byteMerger(body.getBytes(StandardCharsets.UTF_8), data);
        byte[] bytes = ByteArrayUtil.byteMerger(bodyAndPic, tail_str.getBytes(StandardCharsets.UTF_8));

        postMethod.setRequestEntity(new ByteArrayRequestEntity(bytes));
        RequestHandler requestHandler = new RequestHandler();
        String result = requestHandler.sendRequest(postMethod);//{"PictureUrl":"/pic?DE0720170AB0A604C72C*hcs7c58dd92ff6b497d82025/weishiyun/27864;17479922938712503?pic*0*940832*0*DE0720170AB0A604C72C-2*1747992293"}       JSONObject json1 = new JSONObject(result);
        String url = new JSONObject(result).getStr("PictureUrl");
        return url;
    }

    public void downloadImage(String url, String localPath) {
        InputStream inputStream = getImageStream(url);
        FileUtil.writeFromStream(inputStream, localPath);
    }

    public InputStream getImageStream(String url) {
        String gmtTime = GmtTimeUtil.getGmtTime();
        String authorization = poolService.getAuth(PREFIX, "", gmtTime, url, 0);
        GetMethod getMethod = new GetMethod("http://" + poolService.getAddress() + url);
        getMethod.addRequestHeader("Accept-language", "zh-cn");
        getMethod.addRequestHeader("Authorization", authorization);
        getMethod.addRequestHeader("Host", poolService.getAddress());
        getMethod.addRequestHeader("Date", gmtTime);
        getMethod.addRequestHeader("Connection", "close");
        RequestHandler requestHandler = new RequestHandler();
        return requestHandler.sendRequestReturnStream(getMethod);
    }


    public String generateRequestBody(String serialID, String token, int picLen) {
        StringBuilder body = new StringBuilder(divide + endStr);
        body.append(" Content-Disposition: form-data;")
                .append(" name=\"SerialID\"" + endStr + endStr + serialID + endStr + divide + endStr + "Content-Disposition: form-data;")
                .append(" name=\"PoolID\"" + endStr + endStr + HikPoolService.imagePoolId + endStr + divide + endStr + "Content-Disposition: form-data;")
                .append(" name=\"TimeStamp\"" + endStr + endStr + "12345678" + endStr + divide + endStr + "Content-Disposition: form-data;")
                .append(" name=\"PictureType\"" + endStr + endStr + 2 + endStr + divide + endStr + "Content-Disposition: form-data;")
                .append(" name=\"Token\"" + endStr + endStr + token + endStr + divide + endStr + "Content-Disposition: form-data;")
                .append(" name=\"PictureLength\"" + endStr + endStr + picLen + endStr + divide + endStr + "Content-Disposition: form-data;")
                .append(" name=\"Picture\"" + endStr + "Content-Type: " + "image/bmp" + endStr + endStr);

        return body.toString();
    }


    private PostMethod generateHttpHeader(PostMethod postMethod, String gmtTime, String authorization) {
        postMethod.setRequestHeader("Host", poolService.getAddress());
        postMethod.setRequestHeader("Accept-Language", "zh-cn");
        postMethod.setRequestHeader("Authorization", authorization);
        postMethod.setRequestHeader("Date", gmtTime);
        postMethod.setRequestHeader("Content-Type", contentType + ";boundary=" + boundaryStr);
        postMethod.setRequestHeader("Connection", "keep-alive");
        return postMethod;
    }


}
